import 'package:dio/dio.dart';
import 'package:dk_flutter_base/dk_core.dart';

mixin ClientMixIn on BaseHttpClient {
  ///默认添加[DefaultRequestInterceptor]拦截器
  void addInterceptor(Interceptors interceptors) {
    interceptors.add(DefaultRequestInterceptor());
  }

  ///实现父类网络 成功 处理
  void checkSuccessResponse(Response<Map<String, dynamic>> response,
      Function successCallback, Function failCallback) {
    if (null == response) {
      if (null != failCallback) {
        handleFailCallBack(
            failCallback, DefaultHttpError(response.statusCode, "没有响应体"), null);
      }
      return;
    }
    //请求成功 2开头表示成功处理了请求的状态代码。
    if (response.statusCode < 200 || response.statusCode >= 300) {
      if (null != failCallback) {
        handleFailCallBack(
            failCallback, DefaultHttpError(response.statusCode, "请求错误"), null);
      }
      return;
    }
    //没有响应数据
    if (null == response.data) {
      if (null != failCallback) {
        handleFailCallBack(failCallback,
            DefaultHttpError(response.statusCode, "没有响应数据"), null);
      }
      return;
    }
    DefaultResponseData responseData =
        DefaultResponseData.fromJson(response.data);
    //没有code
    if (null == responseData.code || responseData.code.length <= 0) {
      if (null != failCallback) {
        handleFailCallBack(failCallback,
            DefaultHttpError(response.statusCode, "没有业务码信息"), null);
      }
      return;
    }
    //业务操作成功
    if (responseData.code == DefaultRequestInterceptor.REQUEST_SUCCESS_CODE) {
      if (null != successCallback) {
        handleSuccessCallBack(successCallback, responseData, true);
      }
      return;
    }
    //处理通用错误业务码
    bool handleNext = handleErrorCode(responseData.code);
    if (null != handleNext && !handleNext) {
      return;
    }
    handleSuccessCallBack(successCallback, responseData, false);
  }

  ///实现父类网络 失败 处理
  @override
  void checkError(dioError, Function successCallback, Function failCallback) {
    if (null == dioError) {
      if (null != failCallback) {
        handleFailCallBack(
            failCallback, DefaultHttpError(1, "错误信息DioError为null"), dioError);
      }
      return;
    }
    /*if (CancelToken.isCancel(dioError)) {
      handleFailCallBack(failCallback, DefaultHttpError(0, "请求取消"), dioError);
    }*/

    if (dioError is DioError) {
      DioErrorType type = dioError.type;
      if (null == type) {
        handleFailCallBack(
            failCallback, DefaultHttpError(2, "未知错误类型"), dioError);
        return;
      }
      switch (type) {
        case DioErrorType.SEND_TIMEOUT:
          handleFailCallBack(
              failCallback, DefaultHttpError(3, "发送数据超时"), dioError);
          break;
        case DioErrorType.CONNECT_TIMEOUT:
          handleFailCallBack(
              failCallback, DefaultHttpError(4, "连接超时"), dioError);
          break;
        case DioErrorType.CANCEL:
          break;
        case DioErrorType.RECEIVE_TIMEOUT:
          handleFailCallBack(
              failCallback, DefaultHttpError(6, "接收数据超时"), dioError);
          break;
        case DioErrorType.DEFAULT:
          handleFailCallBack(
              failCallback, DefaultHttpError(7, "默认错误"), dioError);
          break;
        case DioErrorType.RESPONSE:
          checkErrorResponse(dioError, successCallback, failCallback);
//        handleFailCallBack(failCallback, DefaultHttpError(8, "响应异常"), dioError);
          break;
        default:
          failCallback(DefaultHttpError(7, "默认错误"), dioError);
      }
    } else {
      handleFailCallBack(failCallback,
          DefaultHttpError(-1, "发起请求错误，错误类型不为DioError"), DioError());
    }
  }

  ///返回bool 标识是否继续处理错误信息
  bool handleErrorCode(String code) {
    return true;
  }

  ///网络响应失败的具体处理
  void checkErrorResponse(
      DioError dioError, Function successCallback, Function failCallback) {
    Response response = dioError.response;
    if (null == response) {
      handleFailCallBack(failCallback, DefaultHttpError(9, "响应体为空"), dioError);
      return;
    }
    //请求重定向-暂时不处理 3开头表示要完成请求，需要进一步操作。 通常，这些状态代码用来重定向。
    if (response.statusCode >= 300 && response.statusCode < 400) {
      handleFailCallBack(
          failCallback,
          DefaultHttpError(10, "需要重定向", statusCode: response.statusCode),
          dioError);
      return;
    }
    //请求失败 网络错误 4开头 这些状态代码表示请求可能出错，妨碍了服务器的处理。
    if (response.statusCode >= 400 && response.statusCode < 500) {
      handleFailCallBack(
          failCallback,
          DefaultHttpError(11, "服务器处理错误", statusCode: response.statusCode),
          dioError);
      return;
    }
    //5开头这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误，而不是请求出错。
    if (response.statusCode >= 500 && response.statusCode < 600) {
      handleFailCallBack(
          failCallback,
          DefaultHttpError(12, "服务器异常", statusCode: response.statusCode),
          dioError);
      return;
    }
    handleFailCallBack(
        failCallback,
        DefaultHttpError(13, "未知服务器错误", statusCode: response.statusCode),
        dioError);
  }

  ///校验成功处理回调，并执行[successCallback]函数，目前只支持[RequestSuccessCallback]
  void handleSuccessCallBack(Function successCallback, DefaultResponseData data,
      bool isBusinessSuccess) {
    if (null == successCallback) {
      return;
    }
    if (successCallback is RequestSuccessCallback) {
      successCallback(data, isBusinessSuccess);
    }
  }

  ///校验成功处理回调，并执行[failCallback]函数
  ///通过传递Function父类以提供不同参数的回调，这里通过判断[failCallback]类型，目只支持[RequestFailCallback]和[RequestFailCallbackFull]
  void handleFailCallBack(Function failCallback,
      DefaultHttpError defaultHttpError, DioError dioError) {
    if (null == failCallback) {
      return;
    }
    if (failCallback is RequestFailCallback) {
      failCallback(defaultHttpError);
    } else if (failCallback is RequestFailCallbackFull) {
      failCallback(defaultHttpError, dioError);
    }
  }
}
